/***********************************************
 **** 版权声明处 **
 ****  为了方便阅读和维护，请严格遵守相关代码规范，谢谢   ****
 *******************************************/
package bpm.graphic
{
	/*******************************************
	 **** huangjixin,2012-10-16,上午9:17:35 **
	 **** 请一句话表述该类主要作用  **
	 *******************************************/
	import bpm.graphic.decorators.DecoratorManager;
	import bpm.graphic.decorators.DecoratorPlayer;
	import bpm.graphic.decorators.DrawMouseMoveRect;
	import bpm.graphic.events.DiagramEditorEvent;
	import bpm.graphic.events.GraphEvent;
	import bpm.graphic.skins.SequenceFlowSkin;
	
	import flash.display.InteractiveObject;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	import flash.utils.Dictionary;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.core.ClassFactory;
	import mx.core.FlexGlobals;
	import mx.core.IVisualElement;
	import mx.core.IVisualElementContainer;
	import mx.core.UIComponent;
	import mx.events.DragEvent;
	import mx.events.FlexEvent;
	import mx.managers.DragManager;
	import mx.managers.FocusManager;
	import mx.managers.IFocusManagerComponent;
	
	import spark.components.Application;
	import spark.components.Label;
	import spark.components.Scroller;
	import spark.components.supportClasses.SkinnableComponent;
	
	[Event(name="selectionChange", type="bpm.graphic.events.GraphEvent")]
	public class DiagramEditor extends SkinnableComponent
	{
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 类私有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：private static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 类公有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：public static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 私有变量声明处，请以“_”开头定义变量
		// 例如：private var _example:String;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		private var _canAlign:Boolean;
		
		protected var decoratorManager:DecoratorManager;
		
		private var renerToResizeAdorner:Dictionary;
		
		private var copyObjects:ArrayCollection = new ArrayCollection();
		
		private var selectedGraph:Graph;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 公有变量声明处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		[SkinPart]
		/**
		 * 对应皮肤当中的graph引用 
		 */
		public var grid:Grid;
		
		[SkinPart]
		/**
		 * 对应皮肤当中的graph引用 
		 */
		public var graph:Graph;
		
		[SkinPart]
		/**
		 * 对应皮肤当中的graph引用 
		 */
		public var scroller:Scroller;
		
		[SkinPart]
		/**
		 * 绘制层引用 
		 */
		public var drawingLayer:UIComponent;
		
		[Bindable]
		public var selectedObjects:ArrayCollection = new ArrayCollection();

		
		[Bindable]
		public var showGrid:Boolean = true;
		
		[Bindable]
		public var allowDelete:Boolean = true;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 构造函数，初始化相关工作可以放在里面
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		public function DiagramEditor()
		{
			super();
			
			addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			renerToResizeAdorner = new Dictionary();
		}//构造函数结束
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// getter和setter函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 相关事件响应函数和逻辑函数存放处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 * 
		 * @param event
		 * 
		 */
		protected function onEnterFrame(event:Event):void
		{
			if(graph.stage){
//				removeEventListener(Event.ENTER_FRAME, onEnterFrame);
				
				graph.stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove,true);
				
				graph.stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown,true);
				
				graph.stage.addEventListener(DiagramEditorEvent.EDITOR_CREATE, onEditorCreate);
				
				FlexGlobals.topLevelApplication.doubleClickEnabled = true;
				
				FlexGlobals.topLevelApplication.addEventListener(MouseEvent.DOUBLE_CLICK,onDoubleClick);
				
				
				if(!DecoratorPlayer.drawLayer){
					DecoratorPlayer.drawLayer  = drawingLayer;
					DecoratorPlayer.drawRect(this);
				}
			}
		}
		
		
		
		/**
		 *	 
		 * @param event
		 * 
		 */
		protected function onDoubleClick(event:MouseEvent):void
		{
			var render:Render = graph.getDeeplistRender();
			var graphEvent:GraphEvent;
			if(render){
				if(!graph.contains(render)){
					return;
				}
				
				DecoratorPlayer.displayText(render);
			}else if(event.target == graph){
				graph.setFocus();
			}
		}
		
		
		protected function onEditorReparent(event:DiagramEditorEvent):void
		{
			var render:Render = event.object as Render;
			var graphEvent:GraphEvent;
			graphEvent = new GraphEvent(GraphEvent.SELECTION_CHANGE,render);
			graph.stage.dispatchEvent(graphEvent);
		}
		
		/**
		 * 创建完成以后，清空所有矩形，边饰，selectedObject对象数组清空添加新增对象。 
		 * @param event
		 * 
		 */
		protected function onEditorCreate(event:DiagramEditorEvent):void
		{
			dispatchEvent(event);
			DecoratorPlayer.cleanUp();
			DecoratorPlayer.clearAdorners();
			
			getSelectedObjects(graph);
			clearSelectedObjects();
			
			var render:Render;
			var resizeAdorner:ResizeAdorner;
			if(event.object is Render){
				render = event.object as Render;
				
				selectedObjects.addItem(render);
				render.isSelected = true;
				
				if(renerToResizeAdorner[render]){
					resizeAdorner = renerToResizeAdorner[render];
					resizeAdorner.play();
				}else{
					resizeAdorner = DecoratorPlayer.displayAdorner(render);
					renerToResizeAdorner[render] = resizeAdorner;
				}
			}
		}
		
		/**
		 * 鼠标点击。 
		 * @param event
		 * 
		 */
		protected function onMouseDown(event:MouseEvent):void
		{
			if(event.cancelable){
				return;
			}
			var render:Render = graph.getDeeplistRender();
			var graphEvent:GraphEvent;
			var resizeAdorner:ResizeAdorner;
			if(render){
				if(!graph.contains(render)){
					return;
				}
				this.dispatchEvent(new GraphEvent(GraphEvent.SELECTION_CHANGE,render));
				if(event.ctrlKey){ //考虑按住多选。
//					DecoratorPlayer.clearAdorners();
					
					if(render.isSelected){
						if(renerToResizeAdorner[render]){
							resizeAdorner = renerToResizeAdorner[render];
							resizeAdorner.cleanUp(resizeAdorner);
						}
					}else{
						if(renerToResizeAdorner[render]){
							resizeAdorner = renerToResizeAdorner[render];
							resizeAdorner.play();
						}else{
							resizeAdorner = DecoratorPlayer.displayAdorner(render);
							renerToResizeAdorner[render] = resizeAdorner;
						}
					}
//					this.dispatchEvent(new GraphEvent(GraphEvent.SELECTION_CHANGE,render));
					if(!selectedObjects.contains(render)){
						render.isSelected = true;
						selectedObjects.addItem(render);
					}else{
						render.isSelected = false;
						selectedObjects.removeItemAt(selectedObjects.getItemIndex(render));
					}
				}else{
					render.addEventListener(MouseEvent.MOUSE_DOWN, onRenderMouseDown);
					render.addEventListener(DiagramEditorEvent.EDITOR_DELETE, onDitorDelete);
					
					render.isSelected = true;
//					this.dispatchEvent(new GraphEvent(GraphEvent.SELECTION_CHANGE,render));
					if(!selectedObjects.contains(render)){
						clearSelectedObjects();
						selectedObjects.addItem(render);
					}else{
//						selectedObjects.setItemAt(render,0);
					}
					/*selectedObjects.removeAll();
					getSelectedObjects(graph);*/
					
					DecoratorPlayer.clearAdorners();
					if(renerToResizeAdorner[render]){
						ResizeAdorner(renerToResizeAdorner[render]).play();
					}else{
						resizeAdorner = DecoratorPlayer.displayAdorner(render);
						renerToResizeAdorner[render] = resizeAdorner;
					}
				}
				
				if(!DecoratorPlayer.textEditing){
					UIComponent(render.parent).setFocus();
				}
				
				if(render.hasOwnProperty("graph")){
					selectedGraph = render["graph"]as Graph;
				}
			}else if(event.target == graph){
				/*graphEvent = new GraphEvent(GraphEvent.CLEAR_SELECTION);
				graphEvent.ctrlKey = event.ctrlKey;
				graph.stage.dispatchEvent(graphEvent);*/
				clearSelectedObjects();
				DecoratorPlayer.cleanUp();
				DecoratorPlayer.clearAdorners();
				if(!DecoratorPlayer.textEditing){
					graph.setFocus();
				}
				
				selectedGraph = this.graph;
			}
		}
		
		private var currentTarget:UIComponent;
		private var currentGraph:Object;
		
		private function onDitorDelete(event:DiagramEditorEvent):void{
			var object:Object = event.object;
			if(object && object is Render){
				if(renerToResizeAdorner[object])
					var adorner:ResizeAdorner = renerToResizeAdorner[object] as ResizeAdorner;
					DecoratorPlayer.deleteAdorner(adorner);
					renerToResizeAdorner[object] = null;
			}
			
		}
		/**
		 * 图元移动。 
		 * @param event
		 * 
		 */
		protected function onRenderMouseDown(event:MouseEvent):void
		{
			//必须先截住事件。
			event.stopPropagation();
			
			//先把变量给定义好。
			var currentTarget:UIComponent = event.currentTarget as UIComponent;
			
			//拖拽开始。
			currentTarget.startDrag();
			
			currentTarget.stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			currentTarget.stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			
			this.currentTarget = currentTarget;
			this.currentGraph = graph.getDeeplistGraph(event,this.currentTarget);
			
			for each (var render:Render in selectedObjects) 
			{
				/*render.dymicPro.xDis = this.currentTarget.x - render.x;
				render.dymicPro.yDis = this.currentTarget.y - render.y;*/
				render.dymicPro.x = this.currentTarget.x - render.x;
				render.dymicPro.y = this.currentTarget.y - render.y;
			}
		}
		
		/**
		 * 舞台对象移动。 
		 * @param event
		 * 
		 */
		protected function onStageMouseMove(event:MouseEvent):void
		{
			var rend:Render;
			for each (rend in selectedObjects) 
			{
				if(render!= this.currentTarget){
					rend.x= this.currentTarget.x - rend.dymicPro.x;
					rend.y = this.currentTarget.y - rend.dymicPro.y;
				}
			}
			
			var currentTarget:UIComponent = this.currentTarget;
			var gra:Graph = graph.getDeeplistGraph(event,currentTarget);
			var point:Point;
			if(!currentTarget || !gra){
				return;
			}
			////// 该段代码主要显示矩形框。
			var parentDoc:Object = gra.parentDocument;
			if(gra!= this.graph){
				var hostComponent:Object;
				var render:Render = null;
				if(parentDoc.hasOwnProperty("hostComponent")){
					hostComponent = parentDoc["hostComponent"];
				}
				if(hostComponent is Render){
					render = hostComponent as Render;
				}
				
				if(render){
					point = new Point(render.x,render.y);
					point = render.parent.localToGlobal(point);
					point = graph.globalToLocal(point);
					var rect:Rectangle = new Rectangle(point.x,point.y,render.width,render.height);
					
					DecoratorPlayer.playRect(rect);
				}
			}else{
				DecoratorPlayer.cleanUp();
			}
			
			////////// 该段代码实现不同容器当中的拖拽。
			if(gra != this.currentGraph){
				if(!gra){
					return;
				}
				
				//批量拖拽
				for each (rend in selectedObjects) 
				{
					if(!gra.contain(gra,rend)){
						
						point = new Point(rend.x,rend.y);
						point = rend.parent.localToGlobal(point); //關鍵點；
						point = gra.globalToLocal(point);
						rend.x = point.x;
						rend.y = point.y;
						/*for each (var link:Link in rend.links) 
						{
							if(link)
								IVisualElementContainer(link.parent).setElementIndex(link,IVisualElementContainer(link.parent).numElements-1);
						}*/
						gra.addElement(rend);
						
						gra.setFocus();
						this.currentGraph = gra;
					}
				}
				//单个进行拖拽。
				/*if(!gra.contain(gra,currentTarget)){
					
					point = new Point(currentTarget.x,currentTarget.y);
					point = currentTarget.parent.localToGlobal(point); //關鍵點；
					point = gra.globalToLocal(point);
					currentTarget.x = point.x;
					currentTarget.y = point.y;
					
					if(currentTarget.parent is Graph){
						this.currentGraph.clearSelected();
					}
					
					gra.clearSelected();
					gra.addElement(currentTarget);
					Render(currentTarget).isSelected = true;
					gra.selectedObjects.addItem(currentTarget);
					
					gra.setFocus();
					this.currentGraph = gra;
				}*/
			}else{
				//批量拖拽
				for each (rend in selectedObjects) 
				{
					if(!gra.contain(gra,rend)){
						
						point = new Point(rend.x,rend.y);
						point = rend.parent.localToGlobal(point); //關鍵點；
						point = gra.globalToLocal(point);
						rend.x = point.x;
						rend.y = point.y;
						/*for each (var link:Link in rend.links) 
						{
							if(link)
								IVisualElementContainer(link.parent).setElementIndex(link,IVisualElementContainer(link.parent).numElements-1);
						}*/
						gra.addElement(rend);
						
						gra.setFocus();
						this.currentGraph = gra;	
					}
				}
				//单个拖拽
				/*if(!gra.contain(gra,currentTarget)){
					
					point = new Point(currentTarget.x,currentTarget.y);
					point = currentTarget.parent.localToGlobal(point); //關鍵點；
					point = gra.globalToLocal(point);
					currentTarget.x = point.x;
					currentTarget.y = point.y;
					
					if(currentTarget.parent is Graph){
						Graph(currentTarget.parent).clearSelected();
					}
					
					gra.clearSelected();
					Render(currentTarget).isSelected = true;
					gra.selectedObjects.addItem(currentTarget);
					gra.addElement(currentTarget);
					
					gra.setFocus();
					this.currentGraph = gra;	
				}*/
			}
		}
		
		/**
		 * 
		 * @param event
		 * 
		 */
		protected function onStageMouseUp(event:MouseEvent):void
		{
			var ele:Render;
			for ( var j:int=0; j < selectedObjects.length;j++) 
			{
				ele = selectedObjects[j] as Render;
				ele.dymicPro = new Point();
			}
			
			
			var currentTarget:UIComponent = this.currentTarget;
			currentTarget.stopDrag();
			currentTarget.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			currentTarget.stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			currentTarget.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			currentTarget.removeEventListener(MouseEvent.MOUSE_DOWN, onRenderMouseDown);
			graph.stage.removeEventListener(MouseEvent.MOUSE_DOWN,onMouseDown,true);
			this.currentTarget = null;
			this.currentGraph = null;
			DecoratorPlayer.cleanUp();
		}
		
		/**
		 * 鼠标移动。 
		 * @param event
		 * 
		 */
		protected function onMouseMove(event:MouseEvent):void
		{
			var render:Render = graph.getDeeplistRender();
			if(render){
				if(graph.contains(render)){
					if(DragManager.isDragging){
						if(render.hasOwnProperty("graph")){
							var point:Point = new Point(render.x,render.y);
							point = render.parent.localToGlobal(point);
							point = graph.globalToLocal(point);
							var rect:Rectangle = new Rectangle(point.x,point.y,render.width,render.height);
							
							DecoratorPlayer.playRect(rect);
							DecoratorPlayer.playingAdorner = false;
						}
					}else{
						/*if(DecoratorPlayer.draggingResizeAdorner){
							return;
						}
						DecoratorPlayer.clearAdorners();
						var resizeAdorner:ResizeAdorner;
						if(renerToResizeAdorner[render]){
							ResizeAdorner(renerToResizeAdorner[render]).play();
						}else{
							resizeAdorner = DecoratorPlayer.displayAdorner(render);
							renerToResizeAdorner[render] = resizeAdorner;
						}*/
					}
					
				}
			}else{
				/*if(DecoratorPlayer.draggingResizeAdorner){
					return;
				}*/
				DecoratorPlayer.cleanUp();
//				DecoratorPlayer.clearAdorners();
				
			}
		}
		
		/**
		 * 
		 * @param event
		 * 
		 */
		protected function onKeyDown(event:KeyboardEvent):void
		{
			switch(event.keyCode)
			{
				case Keyboard.DELETE:
				{
					/*var interactiveObject:InteractiveObject = graph.stage.focus;
					if(interactiveObject is Graph){
					Graph(interactiveObject).deleteSelected();
					}*/
					if(allowDelete){
						deleteSelectedObjects();	
					}
				
					break;
				}
				case Keyboard.A:
				{
					if(event.ctrlKey)
						selectAll();
					break;
				}
				case Keyboard.C:
				{
					if(event.ctrlKey)
						copy();
					break;
				}
				case Keyboard.V:
				{
					if(event.ctrlKey)
						paste();
					break;
				}
					
				default:
				{
					break;
				}
			}
		}
		
		/**
		 * 
		 * 
		 */
		private function getSelectedObjects(gra:Graph):void
		{
			for (var i:int = 0; i < gra.numElements; i++) 
			{
				var ele:UIComponent = gra.getElementAt(i) as UIComponent;
				if (ele is Render){
					var render:Render;
					
					if(ele is Render){
						render = ele as Render;
					}
					
					if(!render){
						break;
					}
					
					if(render.isSelected){
						selectedObjects.addItem(render);
					}
					
					
					var graphEle:Graph = null;
					if(ele.hasOwnProperty("graph")){
						graphEle = ele["graph"];
					}
					if(graphEle){
						getSelectedObjects(graphEle);
					}
				}
			}
		}
		
		/**
		 * 将所有对象选中状态改成false。 
		 * 
		 */
		private function clearSelectedObjects():void
		{
			for (var i:int = selectedObjects.length-1; i >=0; i--) 
			{
				var ele:UIComponent = selectedObjects[i];
				var render:Render;
				if(ele is Render){
					render = ele as Render;
					render.isSelected = false;
				}
			}
			selectedObjects.removeAll();
		}
		/**
		 * 删除选中的元素。
		 * 
		 */
		public function deleteSelectedObjects():void
		{
			selectedObjects.removeAll();
			getSelectedObjects(graph);
			
			for (var i:int = selectedObjects.length-1; i >=0; i--) 
			{
				var ele:UIComponent = selectedObjects[i];
				if(ele.parent){
					ele.dispatchEvent(new DiagramEditorEvent(DiagramEditorEvent.EDITOR_DELETE,ele));
					if(ele is Render){
						var links:ArrayCollection = Render(ele).links;
						for each (var link:Link in links) 
						{
							if(link.parent){
								IVisualElementContainer(link.parent).removeElement(link);							
							}
						}
						
					}
					IVisualElementContainer(ele.parent).removeElement(ele);
				}
			}
		}
		
		/**
		 * 根据框选的矩形框设置Node； 
		 * @param interactRect
		 * 
		 */
		public function setNodesSelected(interactRect:Rectangle):void
		{
			//碰撞检测;
			var nElem:int=graph.numElements;
			var visualElem:UIComponent;
			var elementRect:Rectangle;
			for (var i:int=0; i < nElem; i++)
			{
				visualElem=graph.getElementAt(i) as UIComponent;
				if(visualElem is Link){
					var point:Point = new Point();
					point.x = Math.min(Link(visualElem).fallbackStartPoint.x,Link(visualElem).fallbackEndPoint.x);
					point.y = Math.min(Link(visualElem).fallbackStartPoint.y,Link(visualElem).fallbackEndPoint.y);
					point = Link(visualElem).localToGlobal(point);
					point = Link(visualElem).parent.globalToLocal(point);
					
					elementRect=new Rectangle(point.x, point.y, 
						Math.abs(Link(visualElem).fallbackStartPoint.x-Link(visualElem).fallbackEndPoint.x), 
						Math.abs(Link(visualElem).fallbackStartPoint.y-Link(visualElem).fallbackEndPoint.y));
				}else{
					elementRect=new Rectangle(visualElem.x, visualElem.y, visualElem.width, visualElem.height);
				}
				
				var isHit:Boolean=interactRect.intersects(elementRect);  //交叉碰撞
//				var isHit:Boolean=interactRect.containsRect(elementRect);   //包含碰撞
				if (isHit)
				{
					if(visualElem is Node){
						if(!selectedObjects.contains(visualElem)){
							Node(visualElem).isSelected = true;
							selectedObjects.addItem(visualElem);						
						}
					}
				}else{
					Node(visualElem).isSelected = false;
					var index:int = selectedObjects.getItemIndex(visualElem);
					if(index != -1)
						selectedObjects.removeItemAt(index);
				}
			}
			
		}//setNodesSelected结束
		
		/**
		 * 清除所有的元素。 
		 * 
		 */
		public function clear():void
		{
			selectedObjects.removeAll();
			getAll(graph);
			
			for (var i:int = selectedObjects.length -1; i >= 0 ; i--) 
			{
				var ele:IVisualElement = selectedObjects[i];
				ele.dispatchEvent( new DiagramEditorEvent(DiagramEditorEvent.EDITOR_DELETE, ele));
				IVisualElementContainer(ele.parent).removeElement(ele);
			}
		}//clear结束
		
		/**
		 * 获取所有的元素。 
		 * @param gra
		 * 
		 */
		private function getAll(gra:Graph):void
		{
			for (var i:int = 0; i < gra.numElements; i++) 
			{
				var ele:UIComponent = gra.getElementAt(i) as UIComponent;
				if (ele is Render){
					var render:Render;
					
					if(ele is Render){
						render = ele as Render;
					}
					
					if(!render){
						break;
					}
					selectedObjects.addItem(render);
					
					var graphEle:Graph = null;
					if(ele.hasOwnProperty("graph")){
						graphEle = ele["graph"];
					}
					if(graphEle){
						getAll(graphEle);
					}
				}
			}
		}//deleteAll结束
		
		/**
		 * 拷贝。 
		 * 
		 */
		public function copy():void
		{
			copyObjects.removeAll();
			
			for each (var render:Render in selectedObjects) 
			{
				var cloneRender:Render = render.clone() as Render;
				cloneRender.x += cloneRender.width/2;
				cloneRender.y += cloneRender.height/2;
				copyObjects.addItem(cloneRender);
			}
			
		}
		
		/**
		 * 粘贴。 
		 * 
		 */
		public function paste():void
		{
			var interactiveObject:InteractiveObject = graph.stage.focus;
			if(selectedGraph){
				var gra:Graph = selectedGraph;
				clearSelectedObjects();
				for each (var render:Render in copyObjects) 
				{
					var cloneRender:Render = render.clone() as Render;
					gra.addElement(cloneRender);
					cloneRender.isSelected= true;
					selectedObjects.addItem(cloneRender);
				}
				gra.setFocus();
			}
		}
		
		/**
		 * 选中所有的元素。 
		 * 
		 */
		public function selectAll():void
		{
			selectedObjects.removeAll();
			
			for (var i:int = 0; i < graph.numElements; i++) 
			{
				var ele:UIComponent = graph.getElementAt(i) as UIComponent;
				if (ele is Render){
					var render:Render;
					
					if(ele is Render){
						render = ele as Render;
					}
					
					if(!render){
						break;
					}
					render.isSelected = true;
					selectedObjects.addItem(render);
				}
			}
		}
		/**
		 * 前移。 
		 * 
		 */
		public function bringForward():void
		{
			selectedObjects.removeAll();
			getSelectedObjects(graph);
			if(selectedObjects.length == 0)
				return;
			for(var i:int = selectedObjects.length-1;i>=0;i--) 
			{
				var render:Render = selectedObjects[i];
				var num:int = IVisualElementContainer(render.parent).numElements;
				var index:int = IVisualElementContainer(render.parent).getElementIndex(render);
				if(index < num-1){
					IVisualElementContainer(render.parent).setElementIndex(render,index+1);
				}
			}
			graph.setFocus();
		}
		/**
		 * 置顶。 
		 * 
		 */
		public function bringToFront():void
		{
			selectedObjects.removeAll();
			getSelectedObjects(graph);
			if(selectedObjects.length == 0)
				return;
			for(var i:int = selectedObjects.length-1;i>=0;i--) 
			{
				var render:Render = selectedObjects[i];
				var num:int = IVisualElementContainer(render.parent).numElements;
				var index:int = IVisualElementContainer(render.parent).getElementIndex(render);
				if(index < num-1){
					IVisualElementContainer(render.parent).setElementIndex(render,num-1-(selectedObjects.length-1-i));
				}
			}
			graph.setFocus();
		}
		/**
		 * 后移。 
		 * 
		 */
		public function bringBackward():void
		{
			selectedObjects.removeAll();
			getSelectedObjects(graph);
			if(selectedObjects.length == 0)
				return;
			for(var i:int = 0;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				var num:int = IVisualElementContainer(render.parent).numElements;
				var index:int = IVisualElementContainer(render.parent).getElementIndex(render);
				if(index > 0){
					IVisualElementContainer(render.parent).setElementIndex(render,index-1);
				}
			}
			graph.setFocus();
		}
		/**
		 * 置底。 
		 * 
		 */
		public function bringToBack():void
		{
			selectedObjects.removeAll();
			getSelectedObjects(graph);
			if(selectedObjects.length == 0)
				return;
			for(var i:int = 0;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				var num:int = IVisualElementContainer(render.parent).numElements;
				var index:int = IVisualElementContainer(render.parent).getElementIndex(render);
				if(index > 0){
					IVisualElementContainer(render.parent).setElementIndex(render,0 + i);
				}
			}
			graph.setFocus();
		}
		/**
		 * 居左。 
		 * 
		 */
		public function alignLeft():void
		{
			if(selectedObjects.length < 2)
				return;
			var firRender:Render = selectedObjects[0];
			
			for(var i:int = 1;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				if(render.parent == firRender.parent){
					render.x = firRender.x;
				}else{
					var point:Point = new Point(firRender.x,firRender.y);
					point = firRender.parent.localToGlobal(point);
					point = render.parent.globalToLocal(point);
					render.x = point.x;
				}
			}
			graph.setFocus();
		}
		
		/**
		 * 水平居中。 
		 * 
		 */
		public function alignHorizontalCenter():void
		{
			if(selectedObjects.length < 2)
				return;
			var firRender:Render = selectedObjects[0];
			for(var i:int = 1;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				if(render.parent == firRender.parent){
					render.x = firRender.x + firRender.width/2 - render.width/2;
				}else{
					var point:Point = new Point(firRender.x,firRender.y);
					point = firRender.parent.localToGlobal(point);
					point = render.parent.globalToLocal(point);
					render.x = point.x + firRender.width/2 - render.width/2;
				}
			}
			graph.setFocus();
		}
		
		/**
		 * 水平居右。 
		 * 
		 */
		public function alignRight():void
		{
			if(selectedObjects.length < 2)
				return;
			var firRender:Render = selectedObjects[0];
			for(var i:int = 1;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				if(render.parent == firRender.parent){
					render.x = firRender.x + firRender.width - render.width;
				}else{
					var point:Point = new Point(firRender.x,firRender.y);
					point = firRender.parent.localToGlobal(point);
					point = render.parent.globalToLocal(point);
					render.x = point.x + firRender.width - render.width;
				}
			}
			graph.setFocus();
		}
		/**
		 * 居上。 
		 * 
		 */
		public function alignTop():void
		{
			if(selectedObjects.length < 2)
				return;
			var firRender:Render = selectedObjects[0];
			
			for(var i:int = 1;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				if(render.parent == firRender.parent){
					render.y = firRender.y;
				}else{
					var point:Point = new Point(firRender.x,firRender.y);
					point = firRender.parent.localToGlobal(point);
					point = render.parent.globalToLocal(point);
					render.y = point.y;
				}
			}
			graph.setFocus();
		}
		
		/**
		 * 水平居中。 
		 * 
		 */
		public function alignVerticalMiddle():void
		{
			if(selectedObjects.length < 2)
				return;
			var firRender:Render = selectedObjects[0];
			for(var i:int = 1;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				if(render.parent == firRender.parent){
					render.y = firRender.y + firRender.height/2 - render.height/2;
				}else{
					var point:Point = new Point(firRender.x,firRender.y);
					point = firRender.parent.localToGlobal(point);
					point = render.parent.globalToLocal(point);
					render.y = point.y + firRender.height/2 - render.height/2;
				}
			}
			graph.setFocus();
		}
		
		/**
		 * 水平居右。 
		 * 
		 */
		public function alignBottom():void
		{
			if(selectedObjects.length < 2)
				return;
			var firRender:Render = selectedObjects[0];
			for(var i:int = 1;i<selectedObjects.length;i++) 
			{
				var render:Render = selectedObjects[i];
				if(render.parent == firRender.parent){
					render.y = firRender.y + firRender.height - render.height;
				}else{
					var point:Point = new Point(firRender.x,firRender.y);
					point = firRender.parent.localToGlobal(point);
					point = render.parent.globalToLocal(point);
					render.y = point.y + firRender.height - render.height;
				}
			}
			graph.setFocus();
		}
		
		public function connectObjects():void
		{
//			getSelectedObjects(graph);
			if(selectedObjects.length != 2){
				trace(selectedObjects.length);
				return;
			}
			
			var startNode:Node = selectedObjects[0];
			var endNode:Node = selectedObjects[1];
			var link:SequenceFlow = new  ClassFactory(SequenceFlow).newInstance();
			link.setStyle("skinClass",SequenceFlowSkin);
			
			var startNodeGraph:Graph;
			var endNodeGraph:Graph;
			
			if(startNode.parent is Graph){
				startNodeGraph = startNode.parent as Graph;
			}
			
			if(endNode.parent is Graph){
				endNodeGraph = endNode.parent as Graph;
			}
			var gra:Graph = compareGraph(graph,startNodeGraph,endNodeGraph);
			if(graph){
				graph.addElementAt(link,graph.numElements);
			}
			
			link.startNode = startNode;
			link.endNode = endNode;
			link.shapeType = LinkShapeType.STRAIGHT;
			Render(startNode).links.addItem(link);
			Render(endNode).links.addItem(link);
			var startResizeAdorner:ResizeAdorner = renerToResizeAdorner[startNode];
			var endResizeAdorner:ResizeAdorner = renerToResizeAdorner[endNode];
			if(startResizeAdorner && endResizeAdorner){
				link.startPort = startResizeAdorner.CENTER;
				link.endPort = endResizeAdorner.CENTER;
			}else{
				return;
			}
		}//createConnection结束
		
		private function compareGraph(gra:Graph,graph1:Graph,graph2:Graph):Graph{
			for (var i:int = 0; i < gra.numElements; i++) 
			{
				var ele:UIComponent = gra.getElementAt(i) as UIComponent;
				if (ele is Render){
					var graphEle:Graph = null;
					if(ele.hasOwnProperty("graph")){
						graphEle = ele["graph"];
					}
					
					if(graphEle ==graph1){
						return graph2
					}else if(graphEle ==graph2){
						return graph1;
					}
					
					if(graphEle){
						compareGraph(graphEle,graph1,graph2);
					}
				}
			}
			
			return null;
		}
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// override 覆盖函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 *  partAdded覆盖函数，实例化的时候，对相关引用进行相关事件进行侦听
		 * @param partName
		 * @param instance
		 * 
		 */
		override protected function partAdded(partName:String, instance:Object):void{
			super.partAdded(partName,instance);
			if(instance == graph){
				selectedGraph = graph;
			}
		}
	}//类结束
}//包结束